
package com.be.beadmin.project.impl;

import cn.hutool.core.util.ObjectUtil;
import com.be.beadmin.common.entity.PageEntity;
import com.be.beadmin.common.exception.BeadminException;
import com.be.beadmin.common.utils.JpaQueryBuilder;
import com.be.beadmin.common.utils.JpaSortBuilder;
import com.be.beadmin.project.dto.input.InfoAndPage;
import com.be.beadmin.project.dto.input.MasterPlanDto;
import com.be.beadmin.project.dto.input.MasterPlanStageDto;
import com.be.beadmin.project.dto.input.PlanStageDto;
import com.be.beadmin.project.dto.output.MasterPlanAndStageEx;
import com.be.beadmin.project.dto.output.MasterPlanEx;
import com.be.beadmin.project.entity.*;
import com.be.beadmin.project.mapper.MasterPlanMapper;
import com.be.beadmin.project.mapper.MasterPlanMapperEx;
import com.be.beadmin.project.mapper.PlanStageMapper;
import com.be.beadmin.project.mapper.PlanStageMapperEx;
import com.be.beadmin.project.repository.*;
import com.be.beadmin.project.service.BatchPlanService;
import com.be.beadmin.project.service.MasterPlanService;
import com.be.beadmin.project.service.PlanStageService;
import com.be.beadmin.service.dto.output.DictDataEx;
import com.be.beadmin.service.entity.DictData;
import com.be.beadmin.service.entity.DictType;
import com.be.beadmin.service.repository.DictDataRepository;
import com.be.beadmin.service.repository.DictTypeRepository;
import com.be.beadmin.service.service.DictDataService;
import com.be.beadmin.service.service.SerialNumberService;
import com.be.beadmin.service.util.DateUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Order;
import javax.persistence.criteria.Predicate;
import javax.transaction.Transactional;
import java.util.*;
import java.util.function.Function;

/**
 * @author zjm
 * @description 服务实现
 * @date 2023-01-12
 **/
@Service
@RequiredArgsConstructor
public class MasterPlanServiceImpl implements MasterPlanService {

    @Autowired
    private MasterPlanRepository masterPlanRepository;
    @Autowired
    private MasterPlanMapper masterPlanMapper;
    @Autowired
    private MasterPlanMapperEx masterPlanExMapper;
    @Autowired
    private DictTypeRepository dictTypeRepository;
    @Autowired
    private DictDataRepository dictDataRepository;
    @Autowired
    private DictDataService dictDataService;
//    @Autowired
//    private PlanStageRepository dictTypeRepository;

    @Autowired
    private PlanStageService planStageService;
    @Autowired
    private InfoRepository infoRepository;
    @Autowired
    private ProductInfoRepository productInfoRepository;
    @Autowired
    private BatchPlanService batchPlanService;
    @Autowired
    private BatchPlanRepository batchPlanRepository;
    @Autowired
    private BatchProductRepository batchProductRepository;
    @Autowired
    private SerialNumberService serialNumberService;

    @Autowired
    private PlanStageRepository planStageRepository;

    @Autowired
    private PlanStageMapperEx planStageMapperEx;

//    @Autowired
//    private Stand
    @Override
    public Page<MasterPlanEx> getMasterPlanByPage(PageEntity pageEntity) {
        Pageable pageable = PageRequest.of(
                pageEntity.getCurrent() - 1,
                pageEntity.getPageSize());
        Page<MasterPlan> page = masterPlanRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 = JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(MasterPlan_.delete), 0); //过滤为0
                    list.add(pre2);
                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if (pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(MasterPlan_.createTime).as(Date.class)));
                    }
                    return criteriaBuilder.and(list.toArray(p));
                }
                , pageable);
        Page<MasterPlanEx> page1 = page.map(masterPlanExMapper::toEntity);
        System.out.println("MasterPlanEx:"+page1);
        return page1;
    }
    @Transactional
    @Override
    public int addMasterPlan(String infoId) {

        MasterPlan result = masterPlanRepository.findMasterPlanByInfoIdAndDelete(infoId, 0); // 查找主计划

        if(ObjectUtil.isNotEmpty(result)) {
            return -1;//主计划已存在
        }

        Info info = infoRepository.findInfoByIdAndDelete(infoId,0);
        if (info== null) throw new BeadminException("未找到该项目");

        //设计工时，
        List<BatchProduct> batchProducts = batchProductRepository.findBatchProductByInfoIdAndDelete(infoId,0);
        int designPeriod = 3;
        for (BatchProduct batchProduct : batchProducts) {
//            String type = batchProduct.get();
            designPeriod = designPeriod + 11;
        }
        //生产工时
//        MasterPlanStageDto[] masterPlanStageDtoList = getMasterPlanStageInfo();
        // 字典中获取公式时间
        DictType duration = dictTypeRepository.findDictTypeByDictNameAndDelete("项目计划阶段工时", 0);
        HashMap<String,String> masterPlanDuration = dictDataService.getDictDataMapByDictTypeId(duration);
//        masterPlanDuration.get
        // 设置项目相关信息
        MasterPlan masterPlan = new MasterPlan();
        masterPlan.setInfoId(infoId);
        masterPlan.setProjectName(info.getProjectName());
        masterPlan.setMasterPlanCode(info.getProjectCode()+".001");
        masterPlan.setDeliveryDate(info.getDeliveryDate());
        MasterPlan save = masterPlanRepository.save(masterPlan);
        // 设置工时
        DictType workTimeDt = dictTypeRepository.findDictTypeByDictNameAndDelete("默认工期",0);
        if (workTimeDt == null) {
            throw new BeadminException("未找到默认工期字典字段");
        }
        List<PlanStage> planStages = new ArrayList<>();
        List<DictData> dataList = dictDataRepository.findDictDataByDictTypeIdAndDeleteOrderByDictSortDesc(workTimeDt.getId(), 0);


        for (int i = 0; i<dataList.size();i++) {
            PlanStage planStage = new PlanStage();
            DictData dictData = dataList.get(i);
            planStage.setPlanId(save.getId()); // 计划id
            planStage.setStageSort(dictData.getDictSort()); // 阶段排序
            planStage.setStageName(dictData.getKeyName()); // 阶段名
            planStage.setStageDuration(Integer.parseInt(dictData.getKeyValue())); //阶段时长
            if (i == 0) {
                planStage.setStagePlanEndTime(DateUtil.computeDate(masterPlan.getDeliveryDate(),0));
            } else {
                planStage.setStagePlanEndTime(DateUtil.computeDate(planStages.get(i-1).getStagePlanStartTime(),-1*24));
            }
            planStage.setStagePlanStartTime(DateUtil.computeDate(planStage.getStagePlanEndTime(),-1 * planStage.getStageDuration() *24 ));
            planStages.add(planStage);
        }
        planStages.sort(new Comparator<PlanStage>() {
            @Override
            public int compare(PlanStage o1, PlanStage o2) {
                return o1.getStageSort().compareTo(o2.getStageSort());
            }
        });

        planStageRepository.saveAll(planStages);
        // 添加初始批次
        batchPlanService.addInitBatchPlan(masterPlan.getId());
        info.setContractState("已发布");
        infoRepository.save(info);
        return 0;
    }


    @Override
    public void updateMasterPlan(MasterPlanDto masterPlanDto) {
        MasterPlan result = masterPlanRepository.findMasterPlanByIdAndDelete(masterPlanDto.getId(),0);
        MasterPlan masterPlan = masterPlanMapper.toEntity(masterPlanDto);
//        result = updateResult(result,masterPlan);

        masterPlanRepository.save(result);
    }

//    private MasterPlan updateResult(MasterPlan result, MasterPlan masterPlan) {
//        if ( masterPlan == null ) {
//            return result;
//        }
//        Info info = infoRepository.findInfoByIdAndDelete(result.getInfoId(), 0);
//        Date contractDate = info.getContractDate();
//        Date deliveryDate = result.getDeliveryDate();
//        if ( masterPlan.getSerialNo() != null ) {
//            result.setSerialNo( masterPlan.getSerialNo() );
//        }
//
//        if ( masterPlan.getMasterPlanCode() != null ) {
//            result.setMasterPlanCode( masterPlan.getMasterPlanCode() );
//        }
//        if ( masterPlan.getKickoffStartDate() != null ) {
//            if (masterPlan.getKickoffStartDate().after(deliveryDate)) {
//                throw new BeadminException("开工开始时间不能晚于交付日期");
//            }
//            if (masterPlan.getKickoffStartDate().before(contractDate)) {
//                throw new BeadminException("开工开始时间不能早于合同开始日期");
//            }
//            result.setKickoffStartDate( masterPlan.getKickoffStartDate() );
//        }
//        if ( masterPlan.getKickoffEndDate() != null ) {
//            if (masterPlan.getKickoffEndDate().after(deliveryDate)) {
//                throw new BeadminException("开工结束时间不能晚于交付日期");
//            }
//            if (masterPlan.getKickoffEndDate().before(contractDate)) {
//                throw new BeadminException("开工结束时间不能早于合同开始日期");
//            }
//            result.setKickoffEndDate( masterPlan.getKickoffEndDate() );
//        }
//        if (result.getKickoffEndDate().before(result.getKickoffStartDate())) {
//            throw new BeadminException("开工结束时间不能早于开始开始时间");
//        }
//        if ( masterPlan.getKickoffPeriod() != 0 ) {
//            result.setKickoffPeriod( masterPlan.getKickoffPeriod() );
//        }
//        if ( masterPlan.getDesignStartDate() != null ) {
//            if (masterPlan.getDesignStartDate().after(deliveryDate)) {
//                throw new BeadminException("设计开始时间不能晚于交付日期");
//            }
//            if (masterPlan.getDesignStartDate().before(contractDate)) {
//                throw new BeadminException("设计开始时间不能早于合同开始日期");
//            }
//            result.setDesignStartDate( masterPlan.getDesignStartDate() );
//        }
//        if ( masterPlan.getDesignEndDate() != null ) {
//            if (masterPlan.getDesignEndDate().after(deliveryDate)) {
//                throw new BeadminException("设计结束时间不能晚于交付日期");
//            }
//            if (masterPlan.getDesignEndDate().before(contractDate)) {
//                throw new BeadminException("设计结束时间不能早于合同开始日期");
//            }
//            result.setDesignEndDate( masterPlan.getDesignEndDate() );
//        }
//        if (result.getDesignEndDate().before(result.getDesignStartDate())) {
//            throw new BeadminException("设计结束时间不能早于设计开始时间");
//        }
//        if ( masterPlan.getDesignPeriod() != 0 ) {
//            result.setDesignPeriod( masterPlan.getDesignPeriod() );
//        }
//        if ( masterPlan.getPurchaseStartDate() != null ) {
//            if (masterPlan.getPurchaseStartDate().after(deliveryDate)) {
//                throw new BeadminException("采购开始时间不能晚于交付日期");
//            }
//            if (masterPlan.getPurchaseStartDate().before(contractDate)) {
//                throw new BeadminException("采购开始时间不能早于合同开始日期");
//            }
//            result.setPurchaseStartDate( masterPlan.getPurchaseStartDate() );
//        }
//        if ( masterPlan.getPurchaseEndDate() != null ) {
//            if (masterPlan.getPurchaseEndDate().after(deliveryDate)) {
//                throw new BeadminException("采购结束时间不能晚于交付日期");
//            }
//            if (masterPlan.getPurchaseEndDate().before(contractDate)) {
//                throw new BeadminException("采购结束时间不能早于合同开始日期");
//            }
//            result.setPurchaseEndDate( masterPlan.getPurchaseEndDate() );
//        }
//        if (result.getPurchaseEndDate().before(result.getPurchaseStartDate())) {
//            throw new BeadminException("采购结束时间不能早于采购开始时间");
//        }
//        if ( masterPlan.getPurchasePeriod() != 0 ) {
//            result.setPurchasePeriod( masterPlan.getPurchasePeriod() );
//        }
//        if ( masterPlan.getLogistcStartDate() != null ) {
//            if (masterPlan.getLogistcStartDate().after(deliveryDate)) {
//                throw new BeadminException("请料开始时间不能晚于交付日期");
//            }
//            if (masterPlan.getLogistcStartDate().before(contractDate)) {
//                throw new BeadminException("请料开始时间不能早于合同开始日期");
//            }
//            result.setLogistcStartDate( masterPlan.getLogistcStartDate() );
//        }
//        if ( masterPlan.getLogistcEndDate() != null ) {
//            if (masterPlan.getLogistcEndDate().after(deliveryDate)) {
//                throw new BeadminException("请料结束时间不能晚于交付日期");
//            }
//            if (masterPlan.getLogistcEndDate().before(contractDate)) {
//                throw new BeadminException("请料结束时间不能早于合同开始日期");
//            }
//            result.setLogistcEndDate( masterPlan.getLogistcEndDate() );
//        }
//        if (result.getLogistcEndDate().before(result.getLogistcStartDate())) {
//            throw new BeadminException("请料结束时间不能早于请料开始时间");
//        }
//        if ( masterPlan.getLogistcPeriod() != 0 ) {
//            result.setLogistcPeriod( masterPlan.getLogistcPeriod() );
//        }
//        if ( masterPlan.getOrderStartDate() != null ) {
//            if (masterPlan.getOrderStartDate().after(deliveryDate)) {
//                throw new BeadminException("生产开始时间不能晚于交付日期");
//            }
//            if (masterPlan.getOrderStartDate().before(contractDate)) {
//                throw new BeadminException("生产开始时间不能早于合同开始日期");
//            }
//            result.setOrderStartDate( masterPlan.getOrderStartDate() );
//        }
//        if ( masterPlan.getOrderEndDate() != null ) {
//            if (masterPlan.getOrderEndDate().after(deliveryDate)) {
//                throw new BeadminException("生产结束时间不能晚于交付日期");
//            }
//            if (masterPlan.getOrderEndDate().before(contractDate)) {
//                throw new BeadminException("生产结束时间不能早于合同开始日期");
//            }
//            result.setOrderEndDate( masterPlan.getOrderEndDate() );
//        }
//        if (result.getOrderEndDate().before(result.getOrderStartDate())) {
//            throw new BeadminException("生产结束时间不能早于生产开始时间");
//        }
//        if ( masterPlan.getOrderPeriod() != 0 ) {
//            result.setOrderPeriod( masterPlan.getOrderPeriod() );
//        }
//        if ( masterPlan.getInboundStartDate() != null ) {
//            if (masterPlan.getInboundStartDate().after(deliveryDate)) {
//                throw new BeadminException("入库开始时间不能晚于交付日期");
//            }
//            if (masterPlan.getInboundStartDate().before(contractDate)) {
//                throw new BeadminException("入库开始时间不能早于合同开始日期");
//            }
//            result.setInboundStartDate( masterPlan.getInboundStartDate() );
//        }
//        if ( masterPlan.getInboundEndDate() != null ) {
//            if (masterPlan.getInboundEndDate().after(deliveryDate)) {
//                throw new BeadminException("入库结束时间不能晚于交付日期");
//            }
//            if (masterPlan.getInboundEndDate().before(contractDate)) {
//                throw new BeadminException("入库结束时间不能早于合同开始日期");
//            }
//            result.setInboundEndDate( masterPlan.getInboundEndDate() );
//        }
//        if (result.getInboundEndDate().before(result.getInboundStartDate())) {
//            throw new BeadminException("入库结束时间不能早于入库开始时间");
//        }
//        if ( masterPlan.getInboundPeriod() != 0 ) {
//            result.setInboundPeriod( masterPlan.getInboundPeriod() );
//        }
//        if ( masterPlan.getPackStartDate() != null ) {
//            if (masterPlan.getPackStartDate().after(deliveryDate)) {
//                throw new BeadminException("打包开始时间不能晚于交付日期");
//            }
//            if (masterPlan.getPackStartDate().before(contractDate)) {
//                throw new BeadminException("打包开始时间不能早于合同开始日期");
//            }
//            result.setPackStartDate( masterPlan.getPackStartDate() );
//        }
//        if ( masterPlan.getPackEndDate() != null ) {
//            if (masterPlan.getPackEndDate().after(deliveryDate)) {
//                throw new BeadminException("打包结束时间不能晚于交付日期");
//            }
//            if (masterPlan.getPackEndDate().before(contractDate)) {
//                throw new BeadminException("打包结束时间不能早于合同开始日期");
//            }
//            result.setPackEndDate( masterPlan.getPackEndDate() );
//        }
//        if (result.getPackEndDate().before(result.getPackStartDate())) {
//            throw new BeadminException("打包结束时间不能早于打包开始时间");
//        }
//        if ( masterPlan.getPackPeriod() != 0 ) {
//            result.setPackPeriod( masterPlan.getPackPeriod() );
//        }
//        if ( masterPlan.getDeliveryStartDate() != null ) {
//            if (masterPlan.getDeliveryStartDate().after(deliveryDate)) {
//                throw new BeadminException("交货开始时间不能晚于交付日期");
//            }
//            if (masterPlan.getDeliveryStartDate().before(contractDate)) {
//                throw new BeadminException("交货开始时间不能早于合同开始日期");
//            }
//            result.setDeliveryStartDate( masterPlan.getDeliveryStartDate() );
//        }
//        if ( masterPlan.getDeliveryEndDate() != null ) {
//            if (masterPlan.getDeliveryEndDate().after(deliveryDate)) {
//                throw new BeadminException("交货结束时间不能晚于交付日期");
//            }
//            if (masterPlan.getDeliveryEndDate().before(contractDate)) {
//                throw new BeadminException("交货结束时间不能早于合同开始日期");
//            }
//            result.setDeliveryEndDate( masterPlan.getDeliveryEndDate() );
//        }
//        if (result.getDeliveryEndDate().before(result.getDeliveryStartDate())) {
//            throw new BeadminException("交货结束时间不能早于交货开始时间");
//        }
//        if ( masterPlan.getDeliveryPeriod() != 0 ) {
//            result.setDeliveryPeriod( masterPlan.getDeliveryPeriod() );
//        }
//        if ( masterPlan.getReceiptStartDate() != null ) {
//            if (masterPlan.getReceiptStartDate().after(deliveryDate)) {
//                throw new BeadminException("签收开始时间不能晚于交付日期");
//            }
//            if (masterPlan.getReceiptStartDate().before(contractDate)) {
//                throw new BeadminException("签收开始时间不能早于合同开始日期");
//            }
//            result.setReceiptStartDate( masterPlan.getReceiptStartDate() );
//        }
//        if ( masterPlan.getReceiptEndDate() != null ) {
//            if (masterPlan.getReceiptEndDate().after(deliveryDate)) {
//                throw new BeadminException("签收结束时间不能晚于交付日期");
//            }
//            if (masterPlan.getReceiptEndDate().before(contractDate)) {
//                throw new BeadminException("签收结束时间不能早于合同开始日期");
//            }
//            result.setReceiptEndDate( masterPlan.getReceiptEndDate() );
//        }
//        if (result.getReceiptEndDate().before(result.getReceiptStartDate())) {
//            throw new BeadminException("签收结束时间不能早于签收开始时间");
//        }
//        if ( masterPlan.getReceiptPeriod() != 0 ) {
//            result.setReceiptPeriod( masterPlan.getReceiptPeriod() );
//        }
//        if ( masterPlan.getInstallStartDate() != null ) {
//            if (masterPlan.getInstallStartDate().after(deliveryDate)) {
//                throw new BeadminException("安装开始时间不能晚于交付日期");
//            }
//            if (masterPlan.getInstallStartDate().before(contractDate)) {
//                throw new BeadminException("安装开始时间不能早于合同开始日期");
//            }
//            result.setInstallStartDate( masterPlan.getInstallStartDate() );
//        }
//        if ( masterPlan.getInstallEndDate() != null ) {
//            if (masterPlan.getInstallEndDate().after(deliveryDate)) {
//                throw new BeadminException("安装开始时间不能晚于交付日期");
//            }
//            if (masterPlan.getInstallEndDate().before(contractDate)) {
//                throw new BeadminException("安装开始时间不能早于合同开始日期");
//            }
//            result.setInstallEndDate( masterPlan.getInstallEndDate() );
//        }
//        if (result.getInstallEndDate().before(result.getInstallStartDate())) {
//            throw new BeadminException("安装结束时间不能早于安装开始时间");
//        }
//        if ( masterPlan.getInstallPeriod() != 0 ) {
//            result.setInstallPeriod( masterPlan.getInstallPeriod() );
//        }
//        if ( masterPlan.getCommissionStartDate() != null ) {
//            if (masterPlan.getCommissionStartDate().after(deliveryDate)) {
//                throw new BeadminException("调试开始时间不能晚于交付日期");
//            }
//            if (masterPlan.getCommissionStartDate().before(contractDate)) {
//                throw new BeadminException("调试开始时间不能早于合同开始日期");
//            }
//            result.setCommissionStartDate( masterPlan.getCommissionStartDate() );
//        }
//        if ( masterPlan.getCommissionEndDate() != null ) {
//            if (masterPlan.getCommissionEndDate().after(deliveryDate)) {
//                throw new BeadminException("调试开始时间不能晚于交付日期");
//            }
//            if (masterPlan.getCommissionEndDate().before(contractDate)) {
//                throw new BeadminException("调试开始时间不能早于合同开始日期");
//            }
//            System.out.println("masterPlan.getCommissionEndDate()"+masterPlan.getCommissionEndDate());
//            result.setCommissionEndDate( masterPlan.getCommissionEndDate() );
//        }
//        if (result.getCommissionEndDate().before(result.getCommissionStartDate())) {
//            throw new BeadminException("调试结束时间不能早于调试开始时间");
//        }
//        if ( masterPlan.getCommissionPeriod() != 0 ) {
//            result.setCommissionPeriod( masterPlan.getCommissionPeriod() );
//        }
//        if ( masterPlan.getFacStartDate() != null ) {
//            if (masterPlan.getFacStartDate().after(deliveryDate)) {
//                throw new BeadminException("验收开始时间不能晚于交付日期");
//            }
//            if (masterPlan.getFacStartDate().before(contractDate)) {
//                throw new BeadminException("验收开始时间不能早于合同开始日期");
//            }
//            result.setFacStartDate( masterPlan.getFacStartDate() );
//        }
//        if ( masterPlan.getFacEndDate() != null ) {
//            if (masterPlan.getFacEndDate().after(deliveryDate)) {
//                throw new BeadminException("验收开始时间不能晚于交付日期");
//            }
//            if (masterPlan.getFacEndDate().before(contractDate)) {
//                throw new BeadminException("验收开始时间不能早于合同开始日期");
//            }
//            result.setFacEndDate( masterPlan.getFacEndDate() );
//        }
//        if (result.getFacEndDate().before(result.getFacStartDate())) {
//            throw new BeadminException("验收结束时间不能早于验收开始时间");
//        }
//        if ( masterPlan.getFacPeriod() != 0 ) {
//            result.setFacPeriod( masterPlan.getFacPeriod() );
//        }
//        if ( masterPlan.getMemo() != null ) {
//            result.setMemo( masterPlan.getMemo() );
//        }
//        if ( masterPlan.getReserved() != null ) {
//            result.setReserved( masterPlan.getReserved() );
//        }
//
//        return result;
//    }


    @Override
    public void delMasterPlan(String id) {
        MasterPlan masterPlan = masterPlanRepository.findMasterPlanById(id);
        batchProductRepository.deleteBatchProductByInfoIdAndDelete(1,masterPlan.getInfoId(),0);//删除批次柜体
        batchPlanRepository.deleteBatchPlanByInfoIdAndDelete(1,masterPlan.getInfoId(),0);//删除批次柜体
        masterPlan.setDelete(1);
        masterPlanRepository.save(masterPlan);
    }

    @Override
    public void delMasterPlans(List<String> ids) {

    }

    /**
     * 第一种方式
     * @return
     */
    @Override
    public MasterPlanStageDto[] getMasterPlanStageInfo() {
        // 项目团队计划阶段类型和时长
        DictType duration = dictTypeRepository.findDictTypeByDictName("项目计划阶段工时");
        DictType field = dictTypeRepository.findDictTypeByDictName("项目计划阶段字段");
        List<DictDataEx> masterPlanDuration = dictDataService.getDictDataExByDictTypeId(duration);
        List<DictDataEx> masterPlanField = dictDataService.getDictDataExByDictTypeId(field);


        MasterPlanStageDto[] masterPlanStageDtos = new MasterPlanStageDto[masterPlanDuration.size()];
        for (int k = 1; k <= masterPlanStageDtos.length; k++) {
            MasterPlanStageDto masterPlanStageDto = new MasterPlanStageDto();
            masterPlanStageDto.setMasterPlanStageOrder(k);
            // 时长
            for (int i = 0; i < masterPlanDuration.size(); i++) {
                if (Integer.parseInt(masterPlanDuration.get(i).getReserved()) == k) {
                    masterPlanStageDto.setMasterPlanStageName(masterPlanDuration.get(i).getKeyName().split("时长")[0]);
                    masterPlanStageDto.setMasterPlanStageDuration(Integer.parseInt(masterPlanDuration.get(i).getKeyValue()));
                }
            }
            // 字段
            for (int j = 0; j < masterPlanField.size(); j++) {
                if (Integer.parseInt(masterPlanField.get(j).getReserved()) == k) {
                    String content = masterPlanField.get(j).getKeyValue();
                    masterPlanStageDto.setMasterPlanStageStartField(content + "StartDate");
                    masterPlanStageDto.setMasterPlanStageEndField(content + "EndDate");
                    masterPlanStageDto.setMasterPlanStageDurationField(content + "Period");
                }
            }
            masterPlanStageDtos[k-1] = masterPlanStageDto;
        }
        return masterPlanStageDtos;
    }

    /**
     * 根据项目ID获取项目计划分页信息
     *
     * @param infoAndPage
     * @return
     */
    @Override
    public Page<MasterPlanEx> getMasterPlanByPageAndInfoId(InfoAndPage infoAndPage) {
        PageEntity pageEntity = infoAndPage.getPageEntity();
        String infoId = infoAndPage.getInfoId();
        Pageable pageable = PageRequest.of(
                pageEntity.getCurrent() - 1,
                pageEntity.getPageSize());
        Page<MasterPlan> page = masterPlanRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 = JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(MasterPlan_.delete), 0); //过滤为0
                    list.add(pre2);
                    Predicate pre3 = criteriaBuilder.equal(root.get(MasterPlan_.infoId), infoId); //过滤为0
                    list.add(pre3);
                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if (pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(MasterPlan_.createTime).as(Date.class)));
                    }
                    return criteriaBuilder.and(list.toArray(p));
                }
                , pageable);
        Page<MasterPlanEx> page1 = page.map(masterPlanExMapper::toEntity);
        System.out.println("MasterPlanEx:"+page1);
        return page1;
    }

    @Override
    public List<PlanStage> getStagesByInfoId(String infoId) {
        MasterPlan masterPlan = masterPlanRepository.findMasterPlanByInfoIdAndDelete(infoId, 0);
        return planStageRepository.findPlanStagesByPlanIdAndDeleteOrderByStageSort(masterPlan.getId(),0);
    }

    @Override
    public List<PlanStage> getStagesByInfoBatchPlanId(String batchPlanId){
        return planStageRepository.findPlanStagesByPlanIdAndDeleteOrderByStageSort(batchPlanId, 0);
    }
    /**
     * 获取项目计划及各阶段分页信息
     *
     * @param pageEntity
     * @return
     */
    @Override
    public Page<MasterPlanAndStageEx> getMasterPlanAndStageByPage(PageEntity pageEntity) {
        Pageable pageable = PageRequest.of(
                pageEntity.getCurrent() - 1,
                pageEntity.getPageSize());
        Page<MasterPlan> page = masterPlanRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 = JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(MasterPlan_.delete), 0); //过滤为0
                    list.add(pre2);
                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if (pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(MasterPlan_.createTime).as(Date.class)));
                    }
                    return criteriaBuilder.and(list.toArray(p));
                }
                , pageable);
//        Page<MasterPlanEx> page1 = page.map(masterPlanExMapper::toEntity);
//        System.out.println("MasterPlanEx:"+page1);
        Page<MasterPlanAndStageEx> map = page.map(new Function<MasterPlan, MasterPlanAndStageEx>() {
            @Override
            public MasterPlanAndStageEx apply(MasterPlan masterPlan) {
                MasterPlanAndStageEx masterPlanAndStageEx = new MasterPlanAndStageEx();
                List<PlanStage> planStages = planStageRepository.findPlanStagesByPlanIdAndDeleteOrderByStageSort(masterPlan.getId(), 0);
                masterPlanAndStageEx.setMasterPlanEx(masterPlanExMapper.toEntity(masterPlan));
                masterPlanAndStageEx.setPlanStagesEx(planStageMapperEx.toEntity(planStages));
                return masterPlanAndStageEx;
            }
        });

        return map;
    }

    /**
     * 修改一个项目主计划各阶段时间
     *
     * @param planStageDtos
     */
    @Transactional
    @Override
    public void updateMasterPlanStageTime(List<PlanStageDto> planStageDtos) {
        if (planStageDtos.size() == 0) {
            return;
        }
        if (planStageDtos.size() == 0) throw new BeadminException("没有传入阶段计划时间参数为空");

        List<PlanStage> planStages = new ArrayList<>();

        planStageDtos.forEach(planStageDto -> {
            PlanStage planStage = planStageService.toEntity(planStageDto);

            planStages.add(planStage);
        });
        // 排一下序
        planStages.sort(new Comparator<PlanStage>() {
            @Override
            public int compare(PlanStage o1, PlanStage o2) {
                return o1.getStageSort().compareTo(o2.getStageSort());
            }
        });

        // 检测一下时间， 开始不能晚于结束， 所有时间不能晚于交付时间
        PlanStage planStage1 = planStages.get(0);
        PlanStage planStagePre = null;
        MasterPlan masterPlanByIdAndDelete = masterPlanRepository.findMasterPlanByIdAndDelete(planStage1.getPlanId(), 0);
        if (masterPlanByIdAndDelete == null) {
            throw new BeadminException("未找到这批阶段的主计划");
        }
        Date deliveryDate = DateUtil.transDateFormat(masterPlanByIdAndDelete.getDeliveryDate());

        for (int i = 0; i < planStages.size() ; i++) {
            PlanStage planStage = planStages.get(i);
//            PlanStage planStageByIdAndDelete = planStageRepository.findPlanStageByIdAndDelete(planStage.getId(), 0);
//            if (planStageByIdAndDelete == null) {
//                throw new BeadminException("未找到ID为"+planStageByIdAndDelete.getId()+"的项目阶段");
//            }
//            if (ObjectUtil.isEmpty(planStageDto.getStagePlanStartTime())) planStageDto.setStagePlanStartTime(planStageByIdAndDelete.getStagePlanStartTime());
//            if (ObjectUtil.isEmpty(planStageDto.getStagePlanEndTime())) planStageDto.setStagePlanEndTime(planStageByIdAndDelete.getStagePlanStartTime());
//            if (ObjectUtil.isEmpty(planStageDto.getStageSort())) planStageDto.setStageSort(planStageByIdAndDelete.getStageSort());

            if (planStage.getStagePlanStartTime() != null && DateUtil.transDateFormat(planStage.getStagePlanStartTime()).after(deliveryDate)) throw new BeadminException(planStage.getStageName()+"计划开始日期不能晚于项目交付日期");
            if (planStage.getStagePlanEndTime() != null && DateUtil.transDateFormat(planStage.getStagePlanEndTime()).after(deliveryDate)) throw new BeadminException(planStage.getStageName()+"计划结束日期不能晚于项目交付日期");
            if (planStage.getStagePlanStartTime() != null && planStage.getStagePlanEndTime() != null && DateUtil.transDateFormat(planStage.getStagePlanStartTime()).after(DateUtil.transDateFormat(planStage.getStagePlanEndTime()))) throw new BeadminException(planStage.getStageName()+"计划开始时间不能晚于计划开始时间");

            if (i>0){
                planStagePre =  planStages.get(i - 1);
                if (planStagePre == null) {
                    throw new BeadminException("未找到前一个计划");
                }
                if (planStage.getStagePlanStartTime().before(planStagePre.getStagePlanEndTime()))
                    throw new BeadminException(planStage.getStageName() + "计划开始日期不能早于"+planStagePre.getStageName()+"计划结束日期");
            }
//            if ()
        }
//        保存
        planStageRepository.saveAll(planStages);

    }

    /**
     * 第二种方式
     * @return
     */
//    @Override
//    public List<HashMap<String, String>> getMasterPlanStageInfo() {
//        // 项目团队计划阶段类型和时长
//        DictType duration = dictTypeRepository.findDictTypeByDictName("项目计划阶段工时");
//        DictType field = dictTypeRepository.findDictTypeByDictName("项目计划阶段字段");
//        List<DictDataEx> masterPlanDuration = dictDataService.getDictDataByDictTypeId(duration);
//        List<DictDataEx> masterPlanField = dictDataService.getDictDataByDictTypeId(field);
//
//
//
//
////        MasterPlanStageDto[] masterPlanStageDtos = new MasterPlanStageDto[masterPlanDuration.size()];
//        for (int k = 1; k <= masterPlanDuration.size(); k++) {
//            HashMap<String, String> masterPlanStageMap = new HashMap<>();
////            masterPlanStageDto.setMasterPlanStageOrder(k);
////            masterPlanStageMap.put("")
//            // 时长
//            for (int i = 0; i < masterPlanDuration.size(); i++) {
//                if (Integer.parseInt(masterPlanDuration.get(i).getReserved()) == k) {
//                    masterPlanStageMap.put(masterPlanDuration.get(i).getKeyName(),masterPlanDuration.get(i).getKeyValue());
//                    masterPlanStageMap.put("阶段名称",masterPlanDuration.get(i).getKeyName().split("时长")[0]);
////                    masterPlanStageDto.setMasterPlanStageName(masterPlanDuration.get(i).getKeyName());
////                    masterPlanStageDto.setMasterPlanStageDuration(Integer.parseInt(masterPlanDuration.get(i).getKeyValue()));
//                }
//            }
//            // 字段
//            for (int j = 0; j < masterPlanField.size(); j++) {
//                if (Integer.parseInt(masterPlanField.get(j).getReserved()) == k) {
//                    String content = masterPlanField.get(j).getKeyValue();
//                    masterPlanStageDto.setMasterPlanStageStartField(content + "StartDate");
//                    masterPlanStageDto.setMasterPlanStageEndField(content + "EndDate");
//                    masterPlanStageDto.setMasterPlanStageDurationField(content + "Period");
//                }
//            }
//            masterPlanStageDtos[k-1] = masterPlanStageDto;
//        }
//        return masterPlanStageDtos;
//    }

}